package com.horay.springbootdemo.async.context.controller;

import com.horay.springbootdemo.common.result.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.context.request.async.WebAsyncTask;

import java.util.concurrent.Callable;
import java.util.function.Consumer;

/**
 * WebAsyncTask异步控制器
 *
 * @author heyingcheng
 * @date 2019/9/2 0:35
 */
@Slf4j
@RestController
@RequestMapping("async/context")
public class DeferredResultAsyncController {

    @Autowired
    private ThreadPoolTaskExecutor deferredResultThreadPoolTaskExecutor;

    @GetMapping("deferred/result")
    public DeferredResult<ResultBody<String>> deferredResult() {
        log.info("DeferredResultAsyncController.deferredResult方法外部线程:[{}]", Thread.currentThread().getName());
        // 设置超时时间
        DeferredResult<ResultBody<String>> result = new DeferredResult<>(10000L);
        // 处理超时事件 采用委托机制
        result.onError(throwable -> {
            log.error("DeferredResultAsyncController.deferredResult方法请求错误", throwable);
        });

        result.onTimeout(() -> {
            log.error("DeferredResultAsyncController.deferredResult方法请求超时");
            result.setResult(ResultBody.RESULT_BODY_FAILURE);
        });

        result.onCompletion(() -> {
            log.info("DeferredResultAsyncController.deferredResult方法执行完成");
        });

        deferredResultThreadPoolTaskExecutor.execute(() -> {
            log.info("DeferredResultAsyncController.deferredResult方法内部线程:[{}]", Thread.currentThread().getName());
            result.setResult(ResultBody.RESULT_BODY_SUCCESS);
        });

        return result;
    }

}
